//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2009-01-01
// Contains ...
// Class to represent one MIDI tone.
using System;
using System.Globalization;
using System.Text;
using JetBrains.Annotations;
using LargoCommon.Abstract;
using LargoCommon.Music;
namespace LargoCommon.Midi
{
///
/// Midi Tone.
///
public sealed class MidiTone : IMidiTone
{
///
/// Initializes a new instance of the MidiTone class.
///
/// Start time.
/// The note number.
/// Midi Velocity.
/// The instrument.
/// The channel.
public MidiTone(long startTime, byte noteNumber, byte velocity, byte instrument, MidiChannel channel) {
this.StartTime = startTime;
this.NoteNumber = noteNumber;
this.Note = MusicalProperties.GetNoteNameAndOctave(this.NoteNumber, DefaultValue.HarmonicOrder);
this.Velocity = velocity;
this.InstrumentNumber = instrument;
this.Channel = channel;
this.FirstInBar = false;
//// this.IsReady = false;
this.Loudness = MusicalProperties.LoudnessOfVelocity(this.Velocity);
}
///
/// Initializes a new instance of the class.
///
[UsedImplicitly]
public MidiTone() {
}
#region Properties
/// Gets The amount of time before tone.
/// General musical property.
public long StartTime { get; }
/// Gets The MIDI note to modify (0x0 to 0x7F).
/// General musical property.
public byte NoteNumber { get; }
/// Gets The Instrument (0x0 to 0x7F).
/// Property description.
public byte InstrumentNumber { get; }
/// Gets The Channel (0x0 to 0x7F).
/// Property description.
public MidiChannel Channel { get; }
/// Gets or sets The amount of time.
/// Property description.
public long Duration { get; set; }
/// Gets or sets Number of bar.
/// Property description.
public int BarNumberFrom { get; set; }
/// Gets or sets Number of bar.
/// Property description.
public int BarNumberTo { get; set; }
/// Gets or sets a value indicating whether Number of bar.
/// Property description.
public bool FirstInBar { [UsedImplicitly] get; set; }
///
/// Gets the loudness.
///
///
/// Property description.
///
public MusicalLoudness Loudness { get; }
///
/// Gets or sets a value indicating whether [sound through].
///
///
/// Property description.
///
public bool SoundThrough { [UsedImplicitly] get; set; }
///
/// Gets a value indicating whether this instance is rhythmic.
///
///
/// True if this instance is rhythmic; otherwise, false.
///
private bool IsRhythmic => this.Channel == MidiChannel.DrumChannel;
///
/// Gets the name of the instrument.
///
///
/// The name of the instrument.
///
private string InstrumentName {
get {
var s = this.IsRhythmic ? ((MidiRhythmicInstrument)this.InstrumentNumber).ToString() : ((MidiMelodicInstrument)this.InstrumentNumber).ToString();
return s;
}
}
/// Gets The velocity of the note (0x0 to 0x7F).
/// Property description.
private byte Velocity { get; }
#endregion
#region Private Properties
/// Gets The MIDI note to modify (0x0 to 0x7F).
/// General musical property.
private string Note { get; }
#endregion
///
/// Complete Duration.
///
/// End Delta Time.
/// Full length.
/// Given division.
public void CompleteDuration(long endDeltaTime, bool fullLength, int givenDivision) {
//// when note off events are missing
if (this.Duration != 0) {
return;
}
this.Duration = fullLength ? endDeltaTime - this.StartTime : endDeltaTime - this.StartTime - 1;
//// 2019/02 - subtracted 1 from endDeltaTime - e.g. the case endDeltaTime=1440, division=720 gives bar-to 3 instead of 2 ...
var quotient = (double)(endDeltaTime - 1) / givenDivision;
this.BarNumberTo = (int)Math.Floor(quotient) + 1;
}
#region To String
/// Generate a string representation of the event.
/// A string representation of the event.
public override string ToString() {
var sb = new StringBuilder();
//// sb.Append(this.DeltaTime.ToString(CultureInfo.CurrentCulture));
//// sb.Append(" ");
sb.AppendFormat("Note {0}", this.Note);
sb.Append(" (");
sb.Append(this.StartTime.ToString(CultureInfo.CurrentCulture.NumberFormat));
sb.Append("* ");
sb.Append(this.Duration.ToString(CultureInfo.CurrentCulture.NumberFormat));
//// sb.Append(", ");
sb.Append(string.Format(CultureInfo.CurrentCulture, "Bar {0}-{1} ", this.BarNumberFrom, this.BarNumberTo));
//// sb.Append(this.Velocity.ToString(System.Globalization.CultureInfo.CurrentCulture.NumberFormat));
sb.Append(" Instrument:");
sb.Append(this.InstrumentName);
sb.Append(")");
return sb.ToString();
}
#endregion
}
}